This article will demonstrate creating estimates of photosynthetically active radiation (PAR) using the stream_light function. The details and application of this model are detailed in Savoy et al. (2021).
Outline
First, let's take a look at the stream_light function which has the following structure:
stream_light(driver_file, Lat, Lon, channel_azimuth, bottom_width, BH, BS, WL, TH, overhang_height, x_LAD)
Running stream_light model requires a parameter file that describes various site characteristics and a driver file that contains inputs into the model. The first argument for the function (driver_file) is a standardized model driver file that contains total incoming irradiance (W m-2) and leaf area index (LAI) (m^2^ m^-2^) which are used as model inputs. The remaining arguments in the function are parameters that describe site characteristics. On the surface this seems like a large number of parameters;however, this tutorial provides more indepth information on each of these parameters and some simplifying assumptions that can be used to reduce the number of necessary parameters.
There are two necessary components to drive stream_light. First, incoming above canopy total irradiance (W m^-2^) is needed as an input into the radiative transfer model. Second, daily estimates of LAI are needed to determine the attenuation of light by canopies within the radiative transfer model. A set of functions is included in the StreamLightUtils package to help create a standardized model driver file.
The structure of the model driver is as follows:
A driver file with the same structure as above can be made using the make_driver function from StreamLightUtils which has the following structure:
make_driver(site_locs, NLDAS_processed, MOD_processed, write_output, save_dir)
#Make the driver files make_driver( site_locs = sites, NLDAS_processed = NLDAS_processed, MOD_processed = MOD_processed )
Let's take a moment to examine the final structure of the driver file
#Read in a driver file data(NC_NHC_driver) head(NC_NHC_driver)
There are several site parameters required to run stream_light; however, not all of these parameters have built in functions within StreamLightUtils. Similarly, not all parameters are easily obtained nor will they all have equal importance for model performance. Here, we detail the same process used to extract parameter values from Savoy et al. (2021). To begin with, let's revisit the parameters used:
To run the model on multiple sites it is easiest to construct a table of parameters for each site such as the following example.
#Load the example parameter file data(NC_params) head(NC_params, n = 2)
Currently there is no functionality to derive stream azimuth within StreamLightUtils. In the meantime, these can be derived manually using aerial photographs, flowlines, or field derived measurements. Because we have based our model on SHADE2 (Li et al., 2012), we follow their conventions where stream azimuth is measured clockwise from North (see figure below). However, at present both banks are parameterized identically in StreamLight (e.g. only a single tree height is put in instead of the heights of trees on either bank) and so in reality a channel azimuth of 45$^\circ$ and 225$^\circ$ will yield the same results. We only mention this point in case future development may allow for parameterizing banks separately, or in case someone wanted to modify the code on their own to add in this functionality.
Example of deriving azimuth, note the first azimuth of the first example is 45$^\circ$ whereas the second example is 315$^\circ$.
The widths used in this tutorial are from field measurements. However, if field measurements are not available or feasible there are various remotely sensed products such as the NARWidth dataset from Allen & Pavelsky. There are also empirically-derived estimates, such as those from McManamay & DeRolph, 2019.
Without detailed information of bank heights a default value of 0.1m was used for all sites.
Without detailed information of bank slopes a default value of 100 was used for all sites.
Without detailed information of water level a default value of 0.1m was used for all sites.
StreamLightUtils has a built in function to derive tree height using the LiDAR derived estimates of Simard et al. (2011). The function extract_height will retrieve an estimate of tree height (m) based on latitude and longitude and has the following structure:
extract_height(Site_ID, Lat, Lon)
Although this parameter file already contains tree height, the following is an example of how to use this funciton
#Extract tree height extract_height( Site_ID = NC_params[, "Site_ID"], Lat = NC_params[, "Lat"], Lon = NC_params[, "Lon"], site_crs = NC_params[, "epsg_crs"] )
Without detailed information on canopy overhang it was assumed that overhang was 10% of tree height at all sites.
Without detailed information on the height of maximum canopy overhang a value of NA can be used. When overhang_height = NA, the model will default to using 75% of tree height.
Most canopies can be approximated by a spherical distribution of leaf angles (x = 1) (Campbell & Norman, 1998), and so x_LAD was set to 1 at all sites.
First time installation of the StreamLight package from GitHub can be done with the devtools library and once installed, the package can be loaded as normal.
devtools::install_github("psavoy/StreamLight") library("StreamLight")
Estimates of average light across a transect can be estimated using the stream_light function which has the following structure:
stream_light(driver_file, Lat, Lon, channel_azimuth, bottom_width, BH, BS, WL, TH, overhang_height, x_LAD)
As outlined in the previous section on preparing parameter files. In Savoy et al. (2021) we made some simplifying assumptions to facilitate applying this model easily to locations that lacked detailed in situ measurements.
To run the model for a single site simply add the parameters to the function.
#Load the example driver file for NC_NHC data(NC_NHC_driver) #Run the model NC_NHC_modeled <- stream_light( NC_NHC_driver, Lat = 35.9925, Lon = -79.0460, channel_azimuth = 330, bottom_width = 18.9, BH = 0.1, BS = 100, WL = 0.1, TH = 23, overhang = 2.3, overhang_height = NA, x_LAD = 1 )
It is also possible to then loop over multiple sites by wrapping the model in another function and below is an example of this that could be adapted to your own workflow.
#Function for batching over multiple sites batch_model <- function(Site, read_dir, save_dir){ #Get the model driver driver_file <- readRDS(paste(read_dir, "/", Site, "_driver.rds", sep = "")) #Get model parameters for the site site_p <- params[params[, "Site_ID"] == Site, ] #Run the model modeled <- stream_light( driver_file, Lat = site_p[, "Lat"], Lon = site_p[, "Lon"], channel_azimuth = site_p[, "Azimuth"], bottom_width = site_p[, "Width"], BH = site_p[, "BH"], BS = site_p[, "BS"], WL = site_p[, "WL"], TH = site_p[, "TH"], overhang = site_p[, "overhang"], overhang_height = site_p[, "overhang_height"], x_LAD = site_p[, "x"] ) #Save the output saveRDS(modeled, paste(save_dir, "/", Site, "_predicted.rds", sep = "")) } #End batch_model #Applying the model to all sites model_rd <- working_dir model_sd <- working_dir #Running the model lapply( params[, "Site_ID"], FUN = batch_model, read_dir = model_rd, save_dir = model_sd ) #Take a look at the output data(NC_NHC_predicted) NC_NHC_predicted[1:2, ]
The columns are as follows:
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.